package com.webcams.ui.resorts;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Environment;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.webcams.core.location.LocationManagerListener;
import com.webcams.core.location.ResortLocationManager;
import com.webcams.core.resorts.Resort;
import com.webcams.core.resorts.ResortsManager;
import com.webcams.core.utils.Utils;
import com.webcams.ui.R;


public class DepartementsUI extends ListActivity implements LocationManagerListener {

	private boolean isGpsOn;
	private Location location;
	private Menu menu;
	private Map<Resort, Double> cacheDistance;

	public DepartementsUI(){
		super();
		cacheDistance = new HashMap<Resort, Double>(); 
	}

	/** Called when the activity is first created. */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		IconifiedTextListAdapter itla = new IconifiedTextListAdapter(this);
		for(Resort r : ResortsManager.getInstance(this)) {
			itla.addItem(new IconifiedText(r));
		}

		setListAdapter(itla);

		ListView lv = getListView();
		lv.setTextFilterEnabled(true);

		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				launchStation(position);
			}
		});

		ResortLocationManager.getInstance(this).addListener(this);

		onLocationChanged(ResortLocationManager.getInstance(this).getLastLocation());
	}

	protected void launchStation(int j) {
		Intent i = new Intent();
		i.setClass(this, ResortUI.class);
		i.putExtra("id", j);
		startActivity(i);        
	}


	public class IconifiedText implements Comparable<IconifiedText>{

		private Resort resort;

		public IconifiedText(Resort resort) {
			this.resort = resort;
		}

		public String getText() {
			String dist = new String();
			if(isGpsOn && cacheDistance.containsKey(resort)) {
				dist = " ("+(int)Math.floor(cacheDistance.get(resort))+"km)";
			}
			return resort.getName()+dist;
		}

		public Drawable getIcon() {
			File logoLocalFile = resort.getLogoLocalFile(DepartementsUI.this);
			if(logoLocalFile != null) {
				Bitmap bitmap = BitmapFactory.decodeFile(resort.getLogoLocalFile(DepartementsUI.this).getPath());
				if(bitmap != null) {
					return new BitmapDrawable(getResources(), bitmap);
				}
			}
			return null;
		}

		public Resort getResort() {
			return resort;
		}

		@Override
		public int compareTo(IconifiedText other) {
			if(other != null)
				return this.getText().compareTo(other.getText());
			else
				throw new IllegalArgumentException();
		}
	}

	public class IconifiedTextView extends LinearLayout {

		private TextView mText;
		private ImageView mIcon;

		public IconifiedTextView(Context context, IconifiedText it) {
			super(context);

			android.util.TypedValue value = new android.util.TypedValue();
			getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);
			TypedValue.coerceToString(value.type, value.data);
			android.util.DisplayMetrics metrics = new android.util.DisplayMetrics();
			getWindowManager().getDefaultDisplay().getMetrics(metrics);
			float ret = value.getDimension(metrics);

			this.setOrientation(HORIZONTAL);
			mIcon = new ImageView(context);
			mIcon.setImageDrawable(it.getIcon());
			/*File f = Environment.getExternalStorageDirectory();
			if(f.exists() && f.isDirectory() && f.listFiles().length > 0) {
				Toast.makeText(DepartementsUI.this, "SD exists", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(DepartementsUI.this, "SD not exists", Toast.LENGTH_SHORT).show();
			}*/
			if(it.getIcon() != null) {
				mIcon.setPadding(0, (int) ((ret-it.getIcon().getIntrinsicHeight())/2), 5, 0);
			}
			addView(mIcon,  new LinearLayout.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

			LayoutInflater mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			mText = (TextView)mInflater.inflate(android.R.layout.simple_list_item_1, null, false);

			mText.setText(it.getText());
			addView(mText, new LinearLayout.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

		}

		public void setText(String words) {
			mText.setText(words);
		}

		public void setIcon(Drawable bullet) {
			mIcon.setImageDrawable(bullet);
		}
	}

	public class IconifiedTextListAdapter extends BaseAdapter {
		private Context mContext;
		private List<IconifiedText> mItems = new ArrayList<IconifiedText>();

		public static final int NAME_COMPARATOR = 0;
		public static final int DIST_COMPARATOR = 1;

		public IconifiedTextListAdapter(Context context) {
			mContext = context;
		}

		public void addItem(IconifiedText it) { mItems.add(it); }
		public void setListItems(List<IconifiedText> lit) { mItems = lit; }
		public int getCount() { return mItems.size(); }
		public Object getItem(int position) { return mItems.get(position); }
		public boolean areAllItemsSelectable() { return false; }

		public boolean isSelectable(int position) {
			return true;
		}
		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			IconifiedTextView btv;
			if (convertView == null) {
				btv = new IconifiedTextView(mContext, mItems.get(position));
			} else { 
				btv = (IconifiedTextView) convertView;
				btv.setText(mItems.get(position).getText());
				btv.setIcon(mItems.get(position).getIcon());
			}
			btv.setMinimumHeight(60);
			return btv;
		}

		public void setListComparator(int comparator) {
			switch(comparator) {
			case NAME_COMPARATOR:
				Collections.sort(mItems, new NameComparator());
				break;
			case DIST_COMPARATOR:
				Collections.sort(mItems, new DistComparator());
				break;
			}
			this.notifyDataSetChanged();
		}

		public class NameComparator implements Comparator<IconifiedText> {
			@Override
			public int compare(IconifiedText o1, IconifiedText o2) {
				return o1.getResort().getName().compareTo(o2.getResort().getName());
			}
		}


		public class DistComparator implements Comparator<IconifiedText> {
			@Override
			public int compare(IconifiedText o1, IconifiedText o2) {
				Resort r1 = o1.getResort();
				Resort r2 = o2.getResort();
				if(!cacheDistance.containsKey(r1) || !cacheDistance.containsKey(r2)) {
					return 1;
				}
				return cacheDistance.get(r1).compareTo(cacheDistance.get(r2));
			}
		}

	}

	@Override
	public void onLocationChanged(Location l) {

		boolean somethingChanged = false;
		boolean tempGpsState = isGpsOn;

		if(l == null) {
			cacheDistance.clear();
			isGpsOn = false;
		} else {
			isGpsOn = true;
			location = l;
			for(Resort r : ResortsManager.getInstance(this)) {

				double newDist = Utils.round(r.getDistanceFrom(location.getLatitude(), location.getLongitude()),0);
				if(cacheDistance.containsKey(r) && !cacheDistance.get(r).equals(newDist)) {
					somethingChanged = true;
				}
				cacheDistance.put(r, newDist);
			}
		}

		if(somethingChanged || tempGpsState != isGpsOn) {
			if(menu != null) {
				menu.findItem(R.id.resortslist_menu_sortbydist).setEnabled(isGpsOn);
			}
			((BaseAdapter)this.getListAdapter()).notifyDataSetChanged();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_resortlist, menu);
		this.menu = menu;

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.resortslist_menu_sortbyname:
			((IconifiedTextListAdapter)this.getListAdapter()).setListComparator(IconifiedTextListAdapter.NAME_COMPARATOR);
			return true;
		case R.id.resortslist_menu_sortbydist:
			((IconifiedTextListAdapter)this.getListAdapter()).setListComparator(IconifiedTextListAdapter.DIST_COMPARATOR);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected void onDestroy(){
		super.onDestroy();
		ResortLocationManager.getInstance(this).removeListener(this);
	}
}

